home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / inventor / www / workarounds / PointSet2.0.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  4.2 KB  |  136 lines

  1. //
  2. // This is a patch for the Inventor 2.0 SoPointSet node, which will
  3. // generate incorrect normal indices when its startIndex field is not
  4. // zero.
  5. //
  6. // To apply this patch, compile this file into a .o and then link
  7. // the .o before -lInventor.  The linker may give a warning.
  8. // This is normal and expected.
  9. //
  10.  
  11. #include <Inventor/SoPickedPoint.h>
  12. #include <Inventor/SoPrimitiveVertex.h>
  13. #include <Inventor/actions/SoRayPickAction.h>
  14. #include <Inventor/details/SoPointDetail.h>
  15. #include <Inventor/bundles/SoMaterialBundle.h>
  16. #include <Inventor/bundles/SoNormalBundle.h>
  17. #include <Inventor/bundles/SoTextureCoordinateBundle.h>
  18. #include <Inventor/elements/SoComplexityElement.h>
  19. #include <Inventor/elements/SoGLCoordinateElement.h>
  20. #include <Inventor/elements/SoMaterialBindingElement.h>
  21. #include <Inventor/elements/SoNormalBindingElement.h>
  22. #include <Inventor/elements/SoNormalElement.h>
  23. #include <Inventor/misc/SoState.h>
  24. #include <Inventor/nodes/SoPointSet.h>
  25.  
  26. void
  27. SoPointSet::generatePrimitives(SoAction *action)
  28. {
  29.     // When generating primitives for picking, delay computing default
  30.     // texture coordinates
  31.     SbBool forPicking = action->isOfType(SoRayPickAction::getClassTypeId());
  32.  
  33.     SbBool            materialPerPoint, normalPerPoint;
  34.     long            numPts;
  35.     int                curCoord, i;
  36.     SoPrimitiveVertex        pv;
  37.     SoPointDetail        detail;
  38.  
  39.     // Push state, just in case we decide to set the NormalElement
  40.     // because we're doing auto-normal generation.
  41.     SoState *state = action->getState();
  42.     state->push();
  43.     // This extra level of brackets is to make bundle constructors get
  44.     // called before state->pop() is called:
  45.     {
  46.     const SoGLCoordinateElement    *ce = (const SoGLCoordinateElement *)
  47.         SoCoordinateElement::getInstance(action->getState());
  48.  
  49.     // Figure out number of points in set
  50.     curCoord = (int) startIndex.getValue();
  51.     numPts = numPoints.getValue();
  52.     if (numPts == SO_POINT_SET_USE_REST_OF_POINTS)
  53.         numPts = ce->getNum() - curCoord;
  54.  
  55.     materialPerPoint = areMaterialsPerPoint(action);
  56.     normalPerPoint   = areNormalsPerPoint(action);
  57.  
  58.     // Test for auto-normal case; since this modifies an element this
  59.     // MUST BE DONE BEFORE ANY BUNDLES ARE CREATED!
  60.     SbVec3f defaultNormal(0, 0, 1);
  61.     const SoNormalElement *ne = SoNormalElement::getInstance(state);
  62.     if (SoNormalBindingElement::get(state) ==
  63.         SoNormalBindingElement::DEFAULT &&
  64.         curCoord + numPts > ne->getNum()) {
  65.         SoNormalElement::set(state, this, 1, &defaultNormal);
  66.         normalPerPoint = FALSE;
  67.     }
  68.  
  69.     if (forPicking)
  70.         pv.setTextureCoords(SbVec4f(0.0, 0.0, 0.0, 0.0));
  71.  
  72.     pv.setDetail(&detail);
  73.  
  74.     SoNormalBundle            nb(action, FALSE);
  75.     SoTextureCoordinateBundle    tcb(action, FALSE, ! forPicking);
  76.  
  77.     pv.setMaterialIndex(curCoord);
  78.     detail.setMaterialIndex(curCoord);
  79.  
  80.     if (! normalPerPoint) {
  81.         pv.setNormal(nb.get(0));
  82.         detail.setNormalIndex(0);
  83.     }
  84.  
  85.         // Get the complexity element and decide how points will be skipped
  86.     // during processing; note that we don't want to skip anything
  87.     // when picking.
  88.         float cmplxValue = SoComplexityElement::get(action->getState());
  89.         float delta = 1.8 * (0.5 - ((cmplxValue < 0.5) ? cmplxValue : 0.5));
  90.         float fraction = 0.0;
  91.     if (forPicking)
  92.         delta = 0.0;
  93.  
  94.     for (i = 0; i < numPts; i++, fraction += delta) {
  95.  
  96.             // Check to see if this point should be skipped due to complexity
  97.             if (fraction >= 1.0) {
  98.                 fraction -= 1.0;
  99.                 curCoord++;
  100.                 continue;
  101.             }
  102.  
  103.         // Set coordinates, normal, and texture coordinates in
  104.         // detail
  105.  
  106.         pv.setPoint(ce->get3(curCoord));
  107.         detail.setCoordinateIndex(curCoord);
  108.         if (normalPerPoint) {
  109.         pv.setNormal(nb.get(curCoord));
  110.         detail.setNormalIndex(curCoord);
  111.         }
  112.         if (materialPerPoint) {
  113.         pv.setMaterialIndex(curCoord);
  114.         detail.setMaterialIndex(curCoord);
  115.         }
  116.         if (tcb.isFunction()) {
  117.         if (! forPicking)
  118.             pv.setTextureCoords(tcb.get(pv.getPoint(),
  119.                         pv.getNormal()));
  120.         detail.setTextureCoordIndex(0);
  121.         }
  122.         else {
  123.         pv.setTextureCoords(tcb.get(curCoord));
  124.         detail.setTextureCoordIndex(curCoord);
  125.         }
  126.  
  127.         // Generate a point primitive
  128.         invokePointCallbacks(action, &pv);
  129.  
  130.         curCoord++;
  131.     }
  132.  
  133.     }
  134.     state->pop();     // Restore NormalElement
  135. }
  136.